package com.khalil.kkadmin.system.user;

import cn.dev33.satoken.secure.SaSecureUtil;
import com.khalil.kkadmin.common.exception.BusinessException;
import com.khalil.kkadmin.common.exception.ExceptionEnum;
import com.khalil.kkadmin.system.user.domain.SysUser;
import com.khalil.kkadmin.system.user.domain.SysUserRepository;
import com.khalil.kkadmin.system.user.vo.SysUserEditVO;
import com.khalil.kkadmin.system.user.vo.SysUserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Random;

@Service
public class SysUserManager {

    private final static String SUPER_ADMIN_USERNAME = "admin";
    private final static String SUPER_ADMIN_PASSWORD = "123456";

    private final static String DEFAULT_PASSWORD = "123456";

    private final SysUserRepository sysUserRepository;

    public SysUserManager(SysUserRepository sysUserRepository) {
        this.sysUserRepository = sysUserRepository;
    }

    public List<SysUserVO> list() {
        return sysUserRepository.findAll().stream().map(sysUser -> {
            SysUserVO sysUserVO = new SysUserVO();
            BeanUtils.copyProperties(sysUser, sysUserVO);
            sysUserVO.setId(sysUser.getId());
            return sysUserVO;
        }).toList();
    }

    public SysUserEditVO createUser(SysUserEditVO sysUserVO) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserVO, sysUser);
        sysUser.setId(null);
        String slat = generateSlat(16);
        sysUser.setSalt(slat);
        String encryptedPassword = SaSecureUtil.aesEncrypt(slat, DEFAULT_PASSWORD);
        sysUser.setPassword(encryptedPassword);
        sysUser.setCreatedAt(new Date());
        sysUserRepository.save(sysUser);
        return sysUserVO;
    }

    public SysUserEditVO updateUser(SysUserEditVO sysUserVO) {
        String username = sysUserVO.getUsername();
        SysUser sysUser = sysUserRepository.findByUsername(username);
        if (sysUser == null) {
            throw new BusinessException(ExceptionEnum.USER_NOT_EXIST);
        }
        BeanUtils.copyProperties(sysUserVO, sysUser);
        sysUserRepository.save(sysUser);
        return sysUserVO;
    }

    public void deleteUser(Long id) {
        sysUserRepository.deleteById(id);
    }

    public boolean checkPassword(String username, String password) {
        // 判断是不是超级管理员
        if (username.equals(SUPER_ADMIN_USERNAME)) {
            return password.equals(SUPER_ADMIN_PASSWORD);
        }

        SysUser sysUser = sysUserRepository.findByUsername(username);
        if (sysUser == null) {
            throw new BusinessException(ExceptionEnum.USER_NOT_EXIST);
        }
        return sysUser.getPassword().equals(SaSecureUtil.aesEncrypt(sysUser.getSalt(), password));
    }

    public void changePassword(String username, String oldPassword, String newPassword) {
        SysUser sysUser = sysUserRepository.findByUsername(username);
        if (sysUser == null) {
            throw new BusinessException(ExceptionEnum.USER_NOT_EXIST);
        }
        String decryptedPassword = SaSecureUtil.aesEncrypt(sysUser.getSalt(), oldPassword);
        if (sysUser.getPassword().equals(decryptedPassword)) {
            // 旧密码正确
            sysUser.setPassword(SaSecureUtil.aesDecrypt(sysUser.getSalt(), newPassword));
        } else {
            throw new BusinessException(ExceptionEnum.USER_PASSWORD_ERROR);
        }
    }

    /**
     * 根据长度n 获取唯一salt值
     *
     * @param n slat长度
     * @return
     */
    public static String generateSlat(int n) {
        if (n == 0) return "";
        char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            char aChar = chars[new Random().nextInt(chars.length)];
            sb.append(aChar);
        }
        return sb.toString();
    }
}
